package Veterinaria.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

import Veterinaria.excepcion.CodigoDuplicadoExcepcion;
import Veterinaria.excepcion.DAOExcepcion;
import Veterinaria.modelo.Articulo;
import Veterinaria.modelo.DetalleFactura;
import Veterinaria.modelo.Dueno;
import Veterinaria.modelo.Factura;
import Veterinaria.modelo.Persona;
import Veterinaria.modelo.FacturaDetalleTMP;
import Veterinaria.negocio.GestionPersona;
import Veterinaria.util.ConexionBD;

public class FacturaDAO extends BaseDAO {

	public Factura insertarfactura(Factura vo) throws DAOExcepcion, CodigoDuplicadoExcepcion {

		String query = "insert into factura (idfactura,iddueno,fecfactura,total,estado) values(?,?,?,?,?)";

		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		
		if(NoExisteFactura(vo.getCod_factura())){
		
		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setString(1, vo.getCod_factura());
			stmt.setString(2, vo.getoDueno().getCodigo_persona());
			stmt.setString(3, vo.getFecha_factura());
			stmt.setDouble(4, vo.getTotal());
			stmt.setString(5, vo.getEstado());

			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo insertar");
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);

		}
		}
		else throw new CodigoDuplicadoExcepcion(vo.getCod_factura());
		return vo;
	}

	public Factura obtenerfactura(String idfactura) throws DAOExcepcion {

		Factura vo = new Factura();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		GestionPersona persona = new GestionPersona();
		try {
			String query = "select idfactura, iddueno, fecfactura, total, estado from factura where idfactura=?  and estado='1'";
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setString(1, idfactura);
			rs = stmt.executeQuery();
			if (rs.next()) {
				vo.setCod_factura(rs.getString(1));
				Dueno due = persona.obtenerDueno(rs.getString(2));
				vo.setoDueno(due);
				vo.setFecha_factura(rs.getString(4));
				vo.setTotal(rs.getDouble(5));
				vo.setEstado(rs.getString(6));
			}
			else{
				vo = null;
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return vo;
	}

	public DetalleFactura insertarfacturadetalle(DetalleFactura vo)
			throws DAOExcepcion {

		String query = "insert into detalle_factura(idfactura,secuencial,idarticulo,cantidad,total) values(?,?,?,?,?)";

		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;

		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setString(1, vo.getOfacturas().getCod_factura());
			stmt.setInt(2, vo.getSecuencial());
			stmt.setString(3, vo.getOarticulos().getCod_articulo());
			stmt.setInt(4, vo.getCantidad());
			stmt.setDouble(5, vo.getTotal());

			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo insertar");
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}

		return vo;
	}

	public void anularfactura(String idfactura) throws DAOExcepcion {
		String query = "update factura set estado=0 where idfactura=?";

		Connection con = null;
		PreparedStatement stmt = null;
		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setString(1, idfactura);
			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo Anular");
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
	}
    private boolean NoExisteFactura(String idfactura) throws DAOExcepcion {
        return obtenerfactura(idfactura) == null;
    }
	
	public Factura obtener(String idfactura) throws DAOExcepcion {

		Factura vo = new Factura();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		GestionPersona persona = new GestionPersona();
		try {
			String query = "select idfactura, iddueno, fecfactura, total, estado from factura where idfactura=?  and estado=1";
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setString(1, idfactura);
			rs = stmt.executeQuery();
			if (rs.next()) {
				vo.setCod_factura(rs.getString(1));
				Dueno due = persona.obtenerDueno(rs.getString(2));
				vo.setoDueno(due);
				vo.setFecha_factura(rs.getString(3));
				vo.setTotal(rs.getDouble(4));
				vo.setEstado(rs.getString(5));
				return vo;
			}else return null;
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}

	}

	
	public Collection<Factura> obtenerReporteFactura(String numfac, String dueno, String desde, String hasta, String estado) throws DAOExcepcion {
		Collection<Factura> l = new ArrayList<Factura>();
		
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		String query;
		try {
				if (desde.length() > 0 || hasta.length() > 0){
					//System.out.println("Consulta por fechas " + desde.length());
					query = "select distinct c.idfactura, c.iddueno, c.fecfactura, c.total, c.estado, d.nombre, d.apellido " +
							" FROM factura c INNER JOIN persona d WHERE " +
							" c.idfactura like '%" + numfac + "%' " +
							" and c.iddueno like '%" + dueno + "%' " +
							" and c.estado like '%" + estado + "%' " +
							" and d.idpersona=c.iddueno " +
							" and c.fecfatura between '" + desde + "' and '" + hasta + "'" +
							" group by c.idfactura order by c.idfactura asc";
				}
				else {
					//System.out.println("Consultas varias " + desde.length());
					query = "select distinct c.idfactura, c.iddueno, c.fecfactura, c.total, c.estado, d.nombre, d.apellido " +
							" FROM factura c INNER JOIN persona d WHERE " +
							" c.idfactura like '%" + numfac + "%' " +
							" and c.iddueno like '%" + dueno + "%' " +
							" and c.estado like '%" + estado + "%' " +
							" and d.idpersona=c.iddueno " +
							" group by c.idfactura order by c.idfactura asc";
				}
				
				
								
			 con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			// stmt.setString(1, codigo_persona);
			rs = stmt.executeQuery();
			while (rs.next()) {
				Factura vo = new Factura();
				vo.setCod_factura(rs.getString("c.idfactura"));
				vo.setFecha_factura(rs.getString("c.fecfactura"));
				vo.setTotal(rs.getDouble("c.total"));
				vo.setEstado(rs.getString("c.estado"));
												
				Persona pe = new Persona();
				pe.setCodigo_persona(rs.getString("c.iddueno"));
				pe.setNombre_persona(rs.getString("d.nombre"));
				pe.setApellido_persona(rs.getString("d.apellido"));
				
				vo.setoPersona(pe);
				l.add(vo);
			} 
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return l;
	}
    


	public FacturaDetalleTMP insertarfacturadetalleTemporal(FacturaDetalleTMP vo)
			throws DAOExcepcion {

		String query = "insert into facturatmp(idfactura,idarticulo,descripcion,cantidad,total) values(?,?,?,?,?)";

		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;

		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setString(1, vo.getIdfactura());
			stmt.setString(2, vo.getidArticulo());
			stmt.setString(3, vo.getDescripcion());
			stmt.setInt(4, vo.getCantidad());
			stmt.setDouble(5, vo.getTotal());

			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo insertar");
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}

		return vo;
	}	
	public Collection<FacturaDetalleTMP> listartemporal() throws DAOExcepcion {
		Collection<FacturaDetalleTMP> p = new ArrayList<FacturaDetalleTMP>();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			String query = "select * from facturatmp";
			stmt = con.prepareStatement(query);
			rs = stmt.executeQuery();
			while (rs.next()) {
				FacturaDetalleTMP vo = new FacturaDetalleTMP();
				vo.setIdfactura(rs.getString("idfactura"));
				vo.setidArticulo(rs.getString("idarticulo"));
				vo.setDescripcion(rs.getString("descripcion"));
				vo.setCantidad(rs.getInt("cantidad"));
				vo.setTotal(rs.getDouble("total"));
				p.add(vo);
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return p;
	}
	public Collection<DetalleFactura> obtenerDetalleFactura(String idfactura) throws DAOExcepcion {
		Collection<DetalleFactura> l = new ArrayList<DetalleFactura>();
		
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		String query;
		try {
			 
				// System.out.println("En las otras " + tipo);
				query = "SELECT c.secuencial, c.idarticulo, a.descripcion, c.idcita, c.cantidad, c.total " +
						" FROM detalle_factura c INNER JOIN articulo a " +
						" WHERE c.idarticulo=a.idarticulo and c.idfactura='" + idfactura + "' order by c.secuencial asc"; 
				
								
			 con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			// stmt.setString(1, codigo_persona);
			rs = stmt.executeQuery();
			while (rs.next()) {
				DetalleFactura vo = new DetalleFactura();
					
				vo.setSecuencial(rs.getInt("secuencial"));
				vo.setIdcita(rs.getString("c.idcita"));
				vo.setCantidad(rs.getInt("c.cantidad"));
				vo.setTotal(rs.getDouble("c.total"));
				
				Articulo ar = new Articulo();
				
				ar.setCod_articulo(rs.getString("c.idarticulo"));
				ar.setDescripcion(rs.getString("a.descripcion"));
				
				vo.setoArticulo(ar);
				l.add(vo);
			} 
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return l;
	}

	public Factura GenerarCodigoFactura() throws DAOExcepcion {
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		String Cad ="0";
		Integer Num = 0;
		try {
			String query = "Select max(idfactura) as codigo from Factura";
			Factura factura = new Factura();
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			rs = stmt.executeQuery();
			if (rs.next()){
				Cad= rs.getString(1);
				if (Cad==null){
					Cad="0000";
				}
			}	
				Num = Integer.parseInt(Cad.substring(1, Cad.length()));
				Num = Num + 1;
				String convierte = String.valueOf(Num);
				String codigo= "000"+ convierte;
//				codigo=codigo.substring(0, codigo.length());
				
		
				 if(4 <=codigo.length()){  
					 int Inicio = (codigo.length() - 4 );   
					 codigo = codigo.substring(Inicio, codigo.length()); 
					 } 
				 else{   
					 codigo = Cad;  			
				 }
				codigo= "F"+codigo;
				factura.setCod_factura(codigo);
			
			 return factura;
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}

	}	

	public FacturaDetalleTMP eliminarfacturadetalleTemporal(FacturaDetalleTMP vo)
			throws DAOExcepcion {

		String query = "delete from facturatmp where idarticulo=?";

		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;

		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setString(1, vo.getidArticulo());

			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo eliminar");
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}

		return vo;
	}		
	
	public FacturaDetalleTMP EliminarDatosTemporal()
			throws DAOExcepcion {
		String query = "TRUNCATE TABLE facturatmp";
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo Eliminar");
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
	return null;	
	}

	public DetalleFactura insertarfacturadetallecita(DetalleFactura vo)
			throws DAOExcepcion {

		String query = "insert into detalle_factura(idfactura,secuencial,idarticulo,idcita,cantidad,total) values(?,?,?,?,?,?)";

		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;

		try {
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setString(1, vo.getOfacturas().getCod_factura());
			stmt.setInt(2, vo.getSecuencial());
			stmt.setString(3, vo.getOarticulos().getCod_articulo());
			stmt.setString(4, vo.getIdcita());
			stmt.setInt(5, vo.getCantidad());
			stmt.setDouble(6, vo.getTotal());

			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo insertar");
			}

		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}

		return vo;
	}	
	
	
	
}
